home *** CD-ROM | disk | FTP | other *** search
- /* $Id: COMDXF.cpp 1.9 1997/05/12 19:04:17 damien Exp $ */
-
- // Copyright (c) 1990-1995 Ray Dream, Inc. All rights reserved.
-
- #include "math.h"
-
- #ifndef __COMDXF__
- #include "COMDXF.h"
- #endif
-
- #ifndef __RGBHSV__
- #include "rgbhsv.h"
- #endif
-
- #ifndef __3DCOFAIL__
- #include "3DCoFail.h"
- #endif
-
- #ifndef __I3DSHUTI__
- #include "I3DShUti.h"
- #endif
-
- #ifndef __I3DSHTRE__
- #include "I3DShTre.h"
- #endif
-
- #ifndef __I3DSHOBJ__
- #include "I3DShObj.h"
- #endif
-
- #ifndef __I3DSHSCN__
- #include "I3DShScn.h"
- #endif
-
- #ifndef __DXFDLL__
- #include "DXFDll.h"
- #endif
-
- #define kManyFacetsError 0x2BC
- #define kStandardFacetsError 0x1000
- #define kFewfacetsError 0x2000
-
- void Transform(VECTOR3D &res, const MATRIX3D& AA, const VECTOR3D& VV) {
- NUM3D xx,yy,zz;
- xx=VV[0];
- yy=VV[1];
- zz=VV[2];
- res[0]=AA.fix*xx+AA.fjx*yy+AA.fkx*zz;
- res[1]=AA.fiy*xx+AA.fjy*yy+AA.fky*zz;
- res[2]=AA.fiz*xx+AA.fjz*yy+AA.fkz*zz;
- }
-
- void TransformPoint(VECTOR3D &res, const TREETRANSFORM3D &AA,const VECTOR3D& VV) {
- Transform(res, AA.fR, VV);
- res[0]=res[0]*AA.fS;
- res[1]=res[1]*AA.fS;
- res[2]=res[2]*AA.fS;
-
- res[0]+=AA.fT[0];
- res[1]+=AA.fT[1];
- res[2]+=AA.fT[2];
- }
-
- unsigned short QuickFixColorToUShort(NUM3D col) {
- double db;
-
- if (col>1.0) col = 1.0;
- db=(double)col;
- db *= 65535;
- return (unsigned short) db;
- }
-
- short ConvertToDXFColor(const COLOR3D& col) {
- unsigned short dxfColor;
- RDRGBColor rgb;
- RDHSVColor hsv;
-
- rgb.rr = QuickFixColorToUShort(col.R);
- rgb.gg = QuickFixColorToUShort(col.G);
- rgb.bb = QuickFixColorToUShort(col.B);
- RDRGB2HSV(rgb, hsv);
- unsigned short sextant = hsv.hue / 10922;
- if ((((double(hsv.hue)/ 10922) - sextant) < 0.1) && (hsv.saturation > 60000)) //standard colors
- dxfColor = sextant + 1;
- else if (hsv.saturation <3000) { //grays
- short grayBrightness = (short)((long)(4680L + (long)hsv.value ) / 9362);
- switch (grayBrightness) {
- case 0: //black
- dxfColor = 0;
- break;
- case 7: //white
- dxfColor = 7;
- break;
- default://real grays
- dxfColor = 249 + grayBrightness;
- }
- }
- else {
- dxfColor = 10 +
- hsv.hue/273 +
- 2*(unsigned short)(((unsigned short)65535-hsv.value)/13107);
- if (hsv.saturation<32767) dxfColor++;
- dxfColor = ((dxfColor>255)?255:dxfColor);
- } // but here it should not go further than 249
- return (short) dxfColor;
- }
-
- //########################################################################################
- struct DXFWriteFacetStruct {
- I3DShPrimitive* primitive;
- IShFileStream* stream;
- TREETRANSFORM3D* transform;
- char* name;
- ULONG count;
- short color;
- };
-
- void ConvertQuickFixToDouble(const NUM3D num, double &dbl) {
- dbl=(double)num*4.0; //eml : scaling factor (1 DXF unit= 1 inch)
- }
-
- void WriteVertex(IShFileStream* stream, VECTOR3D vertex, short id) {
- double db;
-
- stream->PutLong(1);
- stream->PutLong(id);
- stream->PutEOL();
- ConvertQuickFixToDouble(vertex[0], db);
- stream->PutDouble(db);
- stream->PutEOL();
-
- stream->PutLong(2);
- stream->PutLong(id);
- stream->PutEOL();
- ConvertQuickFixToDouble(vertex[1], db);
- stream->PutDouble(db);
- stream->PutEOL();
-
- stream->PutLong(3);
- stream->PutLong(id);
- stream->PutEOL();
- ConvertQuickFixToDouble(vertex[2], db);
- stream->PutDouble(db);
- stream->PutEOL();
- }
-
- Boolean IsFacetDirect(FACET3D* facet) {
- VECTOR3D NN;
- VECTOR3D AB;
- VECTOR3D AC;
- NUM3D norm;
- NUM3D vectProd;
-
- for (int i=0; i<3; i++) {
- NN[i] = facet->fVertices[0].fNormal[i] + facet->fVertices[1].fNormal[i] + facet->fVertices[2].fNormal[i];
- AB[i] = facet->fVertices[1].fVertex[i] - facet->fVertices[0].fVertex[i];
- AC[i] = facet->fVertices[2].fVertex[i] - facet->fVertices[0].fVertex[i];
- }
- norm=sqrt(SQR(AB[0]) + SQR(AB[1]) + SQR(AB[2]));
- AB[0]/=norm;
- AB[1]/=norm;
- AB[2]/=norm;
- //AB./*Pseudo*/Normalize();
- norm=sqrt(SQR(AC[0]) + SQR(AC[1]) + SQR(AC[2]));
- AC[0]/=norm;
- AC[1]/=norm;
- AC[2]/=norm;
- //AC./*Pseudo*/Normalize();
-
- vectProd =(AB[1]*AC[2] - AB[2]*AC[1]) * NN[0];
- vectProd+=(AB[2]*AC[0] - AB[0]*AC[2]) * NN[1];
- vectProd+=(AB[0]*AC[1] - AB[1]*AC[0]) * NN[2];
- return (vectProd >= 0.0);
- } // end 3.0.3
-
- void WriteFacets(FACET3D* facet, void* privData) {
- VECTOR3D vertex;
- DXFWriteFacetStruct* data = (DXFWriteFacetStruct*)privData;
- IShFileStream* stream = data->stream;
-
- stream->PutLine("0");
- stream->PutLine("3DFACE");
-
- // The name and color HAS to be put in each 3dFace!!
- stream->PutLine("8");
- stream->PutString(data->name);
- stream->PutLong(data->count); // To make sure the name is different for each instance of the same object
- stream->PutEOL();
-
- stream->PutLine("62");
- stream->PutLong(data->color);
- stream->PutEOL();
-
- //-- 3.0.3 YC: output the vertices in the direct trigonometric order
- if (IsFacetDirect(facet)) {
- for (short v=0; v<=2; v++) {
- TransformPoint(vertex, *data->transform, facet->fVertices[v].fVertex);
- WriteVertex(stream, vertex, v);
- }
- }
- else { // 3.0.3 YC (cont.)
- TransformPoint(vertex, *data->transform, facet->fVertices[0].fVertex);
- WriteVertex(stream, vertex, 0);
- TransformPoint(vertex, *data->transform, facet->fVertices[2].fVertex);
- WriteVertex(stream, vertex, 2);
- TransformPoint(vertex, *data->transform, facet->fVertices[1].fVertex);
- WriteVertex(stream, vertex, 1);
- } // 3.0.3 YC end.
- // Fourth point equal to third
- WriteVertex(stream, vertex, 3);
- }
-
- void WriteInstance(IShFileStream* stream, I3DShInstance* anInstance, ULONG count) {
- TREETRANSFORM3D transform;
- char name[255] = "Obj";
- COLOR3D col1, col2;
- short dxfColor;
- I3DShTreeElement* tree;
- I3DShObject* object;
- I3DShPrimitive* primitive;
- DXFWriteFacetStruct ws;
- IUnknown* lightOrCameraInstance = NULL;
-
- // Make sure this is not a light or camera instance
- anInstance->QueryInterface(IID_I3DShCamera, (LPVOID*) &lightOrCameraInstance);
- if (!lightOrCameraInstance)
- anInstance->QueryInterface(IID_I3DShLightsource, (LPVOID*) &lightOrCameraInstance);
- if (lightOrCameraInstance) {
- lightOrCameraInstance->Release();
- return;
- }
-
- object = anInstance->Get3DObject();
- object->QueryInterface(IID_I3DShPrimitive, (LPVOID*) &primitive);
- if (primitive) {
- anInstance->QueryInterface(IID_I3DShTreeElement, (LPVOID*) &tree);
- // Calc Name
- tree->GetName(name);
- char* p;
- int i;
- for (p=name, i=0; i<12 && *p!=0; i++, p++) { // Make the name AutoCAD-friendly
- if (((*p<'a') || (*p>'z')) &&
- ((*p<'A') || (*p>'Z')) &&
- ((*p<'0') || (*p>'9'))) {
- *p = '_';
- }
- }
- *p = '\0';
-
- // Calc color
- anInstance->GetMainColors(&col1, &col2);
- dxfColor = ConvertToDXFColor(col1);
-
- // Fill data structure for call back
- ws.primitive = primitive;
- ws.stream = stream;
- tree->GetGlobalTransform(&transform);
- ws.transform = &transform;
- ws.name = name;
- ws.count = count;
- ws.color = dxfColor;
- /*if (primitive->IsPatchBased()) {
- primitive->EnumPatches(WritePatches, &ws);
- }
- else {
- primitive->EnumFacets(WriteFacets, &ws);
- }*/
- anInstance->EnumFacetsWithConversion(WriteFacets, &ws, TRUE, kStandardFacetsError);
- tree->Release();
- primitive->Release();
- }
-
- gShellUtilities->ProgressIncrement(1);
- }
-
- //########################################################################################
- void WriteDXFBegin(IShFileStream* stream) {
- stream->PutLine("0");
- stream->PutLine("SECTION");
- stream->PutLine("2");
- stream->PutLine("HEADER");
- stream->PutLine("0");
- stream->PutLine("ENDSEC");
-
- stream->PutLine("999");
- stream->PutLine("Created using Ray Dream Designer(R) 3");
-
- stream->PutLine("0");
- stream->PutLine("SECTION");
- stream->PutLine("2");
- stream->PutLine("ENTITIES");
- }
-
- void WriteDXFEnd(IShFileStream* stream) {
- stream->PutLine("0");
- stream->PutLine("ENDSEC");
- stream->PutLine("0");
- stream->PutLine("EOF");
- }
-
- //########################################################################################
-
- TDXFExporter::TDXFExporter() {
- fCRef=0; // Reference Counter
- global_count_Obj++;
- }
-
- TDXFExporter::~TDXFExporter() {
- global_count_Obj--;
- }
-
- // IUnknown Interface :
- HRESULT TDXFExporter::QueryInterface(REFIID riid,LPVOID* ppvObj) {
- *ppvObj=NULL;
-
- // The TDXFExporter knows the interfaces of the parent Objects
- if (IsEqualIID(riid, IID_IUnknown))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExExportFilter))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExDataExchanger))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExtension))
- *ppvObj=(LPVOID)this;
-
- // we must add reference if we return an interface
- if (*ppvObj!=NULL) {
- ((LPUNKNOWN)*ppvObj)->AddRef();
- return NOERROR;
- }
- else {
- return ResultFromScode(E_NOINTERFACE);
- }
- }
-
- ULONG TDXFExporter::AddRef() {
- return fCRef++;
- }
-
- ULONG TDXFExporter::Release() {
- ULONG UnreleaseObject=fCRef--;
-
- if (fCRef==0)
- delete this; // No reference left, so destroy the object
-
- return UnreleaseObject;
- }
-
- // I3DExtension methods :
- I3DExtension* TDXFExporter::Clone() {
- TDXFExporter* theClone = new TDXFExporter;
- if (theClone) {
- theClone->AddRef();
- }
- return theClone;
- }
-
- HRESULT TDXFExporter::ShellUtilitiesInit(IShUtilities* shellUtilities) {
- InitCoFailure(shellUtilities);
- return NOERROR;
- }
-
- // I3DExDataExchanger methods :
- ExtensionDataMap* TDXFExporter::GetExtensionDataMap() {
- return NULL;
- }
-
- void* TDXFExporter::GetExtensionDataBuffer() {
- return NULL; // no data
- }
-
- HRESULT TDXFExporter::ExtensionDataChanged() {
- return NOERROR;
- }
-
- HRESULT TDXFExporter::HandleEvent(ULONG SourceID) {
- return ResultFromScode(E_NOTIMPL);
- }
-
- short TDXFExporter::GetResID() {
- return 128; // this is the view ID in the resource file.
- }
-
- BOOLEAN TDXFExporter::Prepare(I3DShScene* /*scene*/, I3DShTreeElement* /*fatherTree*/) {
- return TRUE;
- }
-
- BOOLEAN TDXFExporter::WantsOptionDialog() {
- return FALSE; // no UI
- }
-
- HRESULT TDXFExporter::NeededDiskSpace(char* /*fullPathName*/, I3DShScene* /*scene*/, I3DShTreeElement* /*fatherTree*/, ULONG* /*diskSpace*/) {
- return NOERROR; // We cannot tell, so we do not do anything...
- }
-
- HRESULT TDXFExporter::DoExport(char* fullPathName, I3DShScene* scene, I3DShTreeElement* /*fatherTree*/) {
- DECLAREVOLATILE(IShFileStream*, stream = NULL);
- ULONG nbInst = 0;
- FailInfo fi;
-
- if (TRY(fi)) {
- nbInst =scene->GetInstancesCount();
-
- gShellUtilities->ProgressStart("Exporting DXF", nbInst);
-
- gShellUtilities->CoCreateInstance(CLSID_StandardFileStream, NULL, CLSCTX_INPROC_SERVER, IID_IShFileStream, (LPVOID*) &stream);
- FailNIL(stream);
- FailOSErr((short)stream->InitFileStream(fullPathName, kShStreamOut));
- stream->SetMacOSInfo(IDTYPE('t','t','x','t'), IDTYPE('T','E','X','T')); // Needed on the Mac, Will not do anything on the PC
-
- WriteDXFBegin(stream);
-
- for (ULONG i=1; i<=nbInst; ++i) {
- WriteInstance(stream, scene->GetInstanceByIndex(i), i);
- }
-
- WriteDXFEnd(stream);
-
- stream->Release();
- gShellUtilities->ProgressDone();
- fi.Success();
- }
- else {
- stream->Release();
- gShellUtilities->ProgressDone();
- fi.ReSignal();
- }
- return NOERROR;
- }
-
- BOOLEAN TDXFExporter::WantsPreview() {
- return FALSE;
- }
-
- HRESULT TDXFExporter::GetPreviewSize(short* /*sizeh*/, short* /*sizev*/) {
- return ResultFromScode(E_NOTIMPL);
- }
-
- HRESULT TDXFExporter::SetPreview(IShRasterOffscreen* /*preview*/) {
- return ResultFromScode(E_NOTIMPL);
- }
-
-